package com.luom.fsp.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luom.fsp.common.ErrorCode;
import com.luom.fsp.constant.CommonConstant;
import com.luom.fsp.exception.BusinessException;
import com.luom.fsp.exception.ThrowUtils;
import com.luom.fsp.mapper.ProductReviewMapper;
import com.luom.fsp.model.dto.productReview.ProductReviewQueryRequest;
import com.luom.fsp.model.entity.Order;
import com.luom.fsp.model.entity.ProductReview;
import com.luom.fsp.model.entity.ProductSKU;
import com.luom.fsp.model.entity.User;
import com.luom.fsp.model.vo.ProductReviewVO;
import com.luom.fsp.service.OrderService;
import com.luom.fsp.service.ProductReviewService;
import com.luom.fsp.service.ProductSKUService;
import com.luom.fsp.service.UserService;
import com.luom.fsp.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 商品评论服务实现
 *
*/
@Service
@Slf4j
public class ProductReviewServiceImpl extends ServiceImpl<ProductReviewMapper, ProductReview> implements ProductReviewService {

    @Resource
    private UserService userService;

    @Resource
    private OrderService orderService;

    @Resource
    private ProductSKUService productSKUService;


    /**
     * 校验数据
     *
     * @param productReview
     * @param add      对创建的数据进行校验
     */
    @Override
    public void validProductReview(ProductReview productReview, boolean add) {
        ThrowUtils.throwIf(productReview == null, ErrorCode.PARAMS_ERROR);

        Long orderId = productReview.getOrderId();
        String content = productReview.getContent();
        Integer rating = productReview.getRating();
        // 创建数据时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isBlank(content), ErrorCode.PARAMS_ERROR, "评论内容不能为空");
            ThrowUtils.throwIf(ObjectUtils.isEmpty(rating), ErrorCode.PARAMS_ERROR,"评分不能为空");
            ThrowUtils.throwIf(ObjectUtils.isEmpty(orderId), ErrorCode.PARAMS_ERROR, "订单不能为空");
        }
    }

    /**
     * 获取查询条件
     *
     * @param productReviewQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<ProductReview> getQueryWrapper(ProductReviewQueryRequest productReviewQueryRequest) {
        QueryWrapper<ProductReview> queryWrapper = new QueryWrapper<>();
        if (productReviewQueryRequest == null) {
            return queryWrapper;
        }
        Long id = productReviewQueryRequest.getId();
        String content = productReviewQueryRequest.getContent();
        String sortField = productReviewQueryRequest.getSortField();
        String sortOrder = productReviewQueryRequest.getSortOrder();
        Long userId = productReviewQueryRequest.getUserId();

        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);

        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取商品评论封装
     *
     * @param productReview
     * @param request
     * @return
     */
    @Override
    public ProductReviewVO getProductReviewVO(ProductReview productReview, HttpServletRequest request) {
        // 对象转封装类
        ProductReviewVO productReviewVO = ProductReviewVO.objToVo(productReview);
        // 查询关联用户信息
        if (productReview.getUserId() != null && productReview.getUserId() > 0) {
            User user = userService.getById(productReview.getUserId());
            productReviewVO.setUserName(user.getUserName());
            productReviewVO.setUserAvatar(user.getAvatarUrl());
        }

        return productReviewVO;
    }

    /**
     * 分页获取商品评论封装
     *
     * @param productReviewPage
     * @param request
     * @return
     */
    @Override
    public Page<ProductReviewVO> getProductReviewVOPage(Page<ProductReview> productReviewPage, HttpServletRequest request) {
        List<ProductReview> productReviewList = productReviewPage.getRecords();
        Page<ProductReviewVO> productReviewVOPage = new Page<>(productReviewPage.getCurrent(), productReviewPage.getSize(), productReviewPage.getTotal());
        if (CollUtil.isEmpty(productReviewList)) {
            return productReviewVOPage;
        }
        // 对象列表 => 封装对象列表
        List<ProductReviewVO> productReviewVOList = productReviewList.stream()
                .map(ProductReviewVO::objToVo)
                .collect(Collectors.toList());

        // 关联查询用户信息
        Set<Long> userIdSet = productReviewList.stream()
                .map(ProductReview::getUserId)
                .collect(Collectors.toSet());
        Map<Long, User> userIdUserMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.toMap(User::getId, Function.identity(), (u1, u2) -> u1));

        // 填充信息
        productReviewVOList.forEach(productReviewVO -> {
            Long userId = productReviewVO.getUserId();
            User user = userIdUserMap.get(userId);
            if (user != null) {
                productReviewVO.setUserName(user.getUserName());
                productReviewVO.setUserAvatar(user.getAvatarUrl());
            }
        });

        productReviewVOPage.setRecords(productReviewVOList);
        return productReviewVOPage;
    }

    // 添加商品评论
    @Transactional
    @Override
    public long addProductReview(ProductReview productReview, HttpServletRequest request) {
        // 数据校验
        validProductReview(productReview, true);
        // 获取订单
        Order order = orderService.getById(productReview.getOrderId());
        if (order == null){
            log.error("订单不存在，订单id：{}", productReview.getOrderId());
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);
        if (!order.getUserId().equals(loginUser.getId())){
            log.error("不能添加别人的评论,订单用户id：{}，评论用户id：{}", order.getUserId(),loginUser.getId());
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "不能添加别人的评论");
        }
        // 获取商品规格
        ProductSKU productSKU = productSKUService.getById(order.getSkuId());
        if (productSKU == null){
            log.error("商品规格不存在，商品规格id：{}", order.getSkuId());
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "商品规格不存在");
        }
        // 填充信息
        productReview.setUserId(loginUser.getId());
        productReview.setSkuId(productSKU.getId());
        productReview.setSkuName(productSKU.getQuantity());
        productReview.setProductId(productSKU.getProductId());
        // 写入数据库
        boolean result = this.save(productReview);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);

        // 改变订单状态
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", order.getId());
        updateWrapper.set("hasReview", 1);
        orderService.update(updateWrapper);

        return productReview.getId();
    }

}
